#include "Snake.h"
#include <cstdlib> // 用于 rand()
#include <ctime>   // 用于 time()

POINT food;

Snake::Snake() {
    body.push_back({ GRID_WIDTH / 2, GRID_HEIGHT / 2 }); // 蛇头
    body.push_back({ GRID_WIDTH / 2, GRID_HEIGHT / 2 + 1 }); // 蛇身的第一个部分
    body.push_back({ GRID_WIDTH / 2, GRID_HEIGHT / 2 + 2 }); // 蛇身的第二个部分
    currentDirection = UP;
    hasMoved = true;
}
void Snake::Move() {
    if (!gameRunning) return; // 如果游戏结束，则不执行移动
    if (isPaused) return;     // 如果暂停，则不执行移动

    POINT newHead = body.front();

    // 根据方向更新新蛇头的位置
    switch (currentDirection) {
    case UP:
        if (newHead.y == 0) {
            gameRunning = false; // 游戏结束
            MessageBox(NULL, L"游戏结束！", L"提示", MB_OK);
            return;              // 停止移动
        }
        newHead.y--;
        break;
    case DOWN:
        if (newHead.y == GRID_HEIGHT - 1) {
            gameRunning = false; // 游戏结束
            MessageBox(NULL, L"游戏结束！", L"提示", MB_OK);
            return;              // 停止移动
        }
        newHead.y++;
        break;
    case LEFT:
        if (newHead.x == 0) {
            gameRunning = false; // 游戏结束
            MessageBox(NULL, L"游戏结束！", L"提示", MB_OK);
            return;              // 停止移动
        }
        newHead.x--;
        break;
    case RIGHT:
        if (newHead.x == GRID_WIDTH - 1) {
            gameRunning = false; // 游戏结束
            MessageBox(NULL, L"游戏结束！", L"提示", MB_OK);
            return;              // 停止移动
        }
        newHead.x++;
        break;
    }

    body.insert(body.begin(), newHead); // 将新的头部插入到蛇身前面
    body.pop_back();                    // 删除最后一个部分
}



void Snake::Grow() {
    score += 10;
    body.push_back(body.back());
}

bool Snake::CheckCollision() {
    const POINT& head = body.front();

    // 检查蛇头是否越界
    if (head.x < 0 || head.x >= GRID_WIDTH || head.y < 0 || head.y >= GRID_HEIGHT) {
        return true; // 碰撞边界
    }

    // 检查蛇头是否与自身的其他部分重叠
    for (size_t i = 1; i < body.size(); ++i) {
        if (head.x == body[i].x && head.y == body[i].y) {
            return true; // 碰撞到自身
        }
    }

    return false; // 没有碰撞
}


void Snake::Draw(HDC hdc) {
    HBRUSH brush = CreateSolidBrush(RGB(0, 255, 0));
    SelectObject(hdc, brush);
    for (const auto& segment : body) {
        Rectangle(hdc, segment.x * 20, segment.y * 20,
            (segment.x + 1) * 20, (segment.y + 1) * 20);
    }
    brush = CreateSolidBrush(RGB(255, 255, 0));
    SelectObject(hdc, brush);
    Rectangle(hdc, body.front().x * 20, body.front().y * 20,
        		(body.front().x + 1) * 20, (body.front().y + 1) * 20); // 绘制蛇头
    DeleteObject(brush);
}

void Snake::DrawGrid(HDC hdc) {
    // 使用淡灰色绘制网格线
    HPEN pen = CreatePen(PS_SOLID, 1, RGB(200, 200, 200)); // 淡灰色
    SelectObject(hdc, pen);
    for (int i = 0; i <= GRID_WIDTH; ++i) {
        MoveToEx(hdc, i * 20, 0, NULL);
        LineTo(hdc, i * 20, GRID_HEIGHT * 20);
    }
    for (int j = 0; j <= GRID_HEIGHT; ++j) {
        MoveToEx(hdc, 0, j * 20, NULL);
        LineTo(hdc, GRID_WIDTH * 20, j * 20);
    }
    DeleteObject(pen); // 删除画笔
}
void Snake::DrawFood(HDC hdc) {
    POINT head = body.front();

    // 检查蛇头是否与食物重叠
    if (head.x == food.x && head.y == food.y) {
        // 如果蛇头与食物重叠，保持蛇头为黄色，跳过食物绘制
        return;
    }

    // 否则绘制食物为红色
    HBRUSH foodBrush = CreateSolidBrush(RGB(255, 0, 0)); // 红色
    SelectObject(hdc, foodBrush);
    Rectangle(hdc, food.x * 20, food.y * 20,
        (food.x + 1) * 20, (food.y + 1) * 20);
    DeleteObject(foodBrush);
}


bool Snake::IsFoodOnSnake(POINT food) {
    for (const auto& segment : body) {
        if (segment.x == food.x && segment.y == food.y) {
            return true; // 食物在蛇身上
        }
    }
    return false; // 食物不在蛇身上
}

void Snake::UpdateSnake() {
    if (!gameRunning)return;
    if (CheckCollision()) {
        gameRunning = false; // 检测到碰撞，结束游戏
        // 可以在这里添加更多的游戏结束逻辑，比如显示消息框
        MessageBox(NULL, L"游戏结束！", L"提示", MB_OK);
        return;
    }

    POINT newHead = body.front();
    if (newHead.x == GetFood().x && newHead.y == GetFood().y) {
        Grow();
        GenerateFood();
    }
    else {
        Move();
        hasMoved = true;
    }
}

void Snake::GenerateFood() {
    do {
        food.x = rand() % GRID_WIDTH;
        food.y = rand() % GRID_HEIGHT;
    } while (IsFoodOnSnake(food)); // 确保食物不在蛇身上
}

POINT Snake::GetFood() {
    return food;
}

void Snake::InitializeGame() {
    srand(static_cast<unsigned>(time(0)));
    GenerateFood();
}
